using System;
using System.Collections.Generic;

namespace ADDDF.Infrastructure
{
    /// <summary>
    /// IRepository interface suitable for a base interface.
    /// </summary>
    public interface IRepository
    {
        void FindByKey(object key, out IAggregateRoot item);

        void FindAll(out IEnumerable<IAggregateRoot> items);

        void Add(IAggregateRoot item);

        void Change(IAggregateRoot item);

        bool Set(IAggregateRoot item);

        void Remove(IAggregateRoot item);
    }

    /// <summary>
    /// Typed IRepository interface for type safety.
    /// </summary>
    public interface IRepository<T> where T : IAggregateRoot
    {
        T FindByKey(object key);
        
        IEnumerable<T> FindAll();
        
        void Add(T item);

        void Change(T item);

        /// <summary>
        /// Also known as: AddOrChange. 
        /// </summary>        
        /// <returns>True if item was added, or false if otherwise.</returns>
        bool Set(T item);
        
        void Remove(T item);
    }

    /// <summary>
    /// Custome repository interface should inherit from this.
    /// Benefit: works well with IUnitOfWork
    /// </summary>
    public interface IRepo<T> : IRepository, IRepository<T>
        where T : IAggregateRoot
    {
    }
}
